package cn.com.chengmandian.bike.service.impl;

import cn.com.chengmandian.agent.utils.AuthUtil;
import cn.com.chengmandian.bike.mapper.EbOperationAreaMapper;
import cn.com.chengmandian.bike.model.EbOperationArea;
import cn.com.chengmandian.bike.model.EbRideOrder;
import cn.com.chengmandian.bike.model.vo.OperationAreaVo;
import cn.com.chengmandian.bike.service.IEbOperationAreaService;
import cn.com.chengmandian.bike.service.IEbRideOrderService;
import cn.com.chengmandian.core.common.utils.LnglatUtil;
import cn.com.chengmandian.core.redis.cache.AgentCacheService;
import cn.com.chengmandian.core.redis.pojo.MapData;
import cn.com.chengmandian.core.web.pojo.AgentUser;
import cn.com.chengmandian.core.web.utils.LocalMapUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 服务区(运营区)配置 服务实现类
 * </p>
 *
 * @author AutoGenerator
 * @since 2021-12-09
 */
@Slf4j
@Service
public class EbOperationAreaServiceImpl extends ServiceImpl<EbOperationAreaMapper, EbOperationArea> implements IEbOperationAreaService {

    @Autowired
    private EbOperationAreaMapper operationAreaMapper;

    @Autowired
    private IEbRideOrderService rideOrderService;

    @Autowired
    private AgentCacheService agentCacheService;

    // 获取运营区列表
    private List<OperationAreaVo> getAreaList() {
        try {
            List<MapData> list = agentCacheService.getAreaList(LocalMapUtil.getAgentInfo().getId());
            List<OperationAreaVo> areaList = new ArrayList<>();
            for(MapData item : list) {
                OperationAreaVo vo = new OperationAreaVo();
                vo.setId(item.getTypeId());
                vo.setLats(item.getLats());
                vo.setLngs(item.getLngs());
                vo.setCenterLat(item.getCenterLat());
                vo.setCenterLng(item.getCenterLng());
                areaList.add(vo);
            }
            return areaList;
        } catch (Exception e) {
            log.error("getAreaList error!", e);
            return operationAreaMapper.getAreaList();
        }
    }

    @Override
    public OperationAreaVo getLocationArea(BigDecimal lng, BigDecimal lat) {
        List<OperationAreaVo> areaList = this.getAreaList();
        if (areaList.isEmpty()) return null;
        if (lng == null || lat == null) return areaList.get(0);
        if (areaList.size() == 1) return areaList.get(0);
        for(OperationAreaVo item : areaList) {
            if (item.getLngs() == null || item.getLats() == null) continue;
            if (LnglatUtil.isInPolygon(lng.doubleValue(), lat.doubleValue(), item.getLngs().split(","), item.getLats().split(","))) {
                return item;
            }
        }
        // 如果用户已登陆
        AgentUser loginUser = AuthUtil.getAgentUser();
        if (loginUser != null) {
            EbRideOrder rideOrder = rideOrderService.getOne(new LambdaQueryWrapper<EbRideOrder>()
                    .eq(EbRideOrder::getMemberId, loginUser.getId())
                    .orderByDesc(EbRideOrder::getId)
                    .last("limit 1"));
            if (rideOrder != null) {
                OperationAreaVo item = areaList.stream().filter(i -> i.getId().equals(rideOrder.getAreaId())).findFirst().get();
                if (item != null) return item;
            }
        }

        // 500公里内离中心点最近的运营区
        double nearDistance = 1000 * 200;
        OperationAreaVo near = null;
        for(OperationAreaVo item : areaList) {
            if (item.getCenterLat() == null || item.getCenterLng() == null) continue;
            double distance = LnglatUtil.getDistance(lng.doubleValue(), lat.doubleValue(), item.getCenterLng().doubleValue(), item.getCenterLat().doubleValue());
            if (distance > nearDistance) continue;;
            nearDistance = distance;
            near = item;
        }
        return near;
    }
}
